/**
* @fileoverview Funciones de utilidad
* 
* @author INEI
* @version 0.1
*/

/**
* Enlaza input:text y textarea por sus id, para poder ir de objeto en objeto 
* presionando la tecla enter
* 
* @param {jQuery} container Objeto jQuery que contiene los elementos a enlazar. Generalmente jQuery('#form1')
*/
function enlazarCajas(container) {
    jQuery('input:text, textarea', jQuery(container)).keypress(function(e) {
        if (e.keyCode == 13) {
            jQuery('#' + (parseInt(jQuery(this).attr('id'), 10) + 1)).focus();
            return false;
        }
		else if(e.keyCode == 9 && !e.shiftKey){
			return false;
		}
    }).focus(function(){
		jQuery(this).addClass('textHover');
	}).blur(function(){
		jQuery(this).removeClass('textHover');
	});
}

/**
* Verifica si el valor es una cadena vac\xeda
* 
* @param {string} str Valor que se desea verificar si es o no una cadena vac\xeda
* @returns {boolean} True, si <b>str</b> es vac\xedo; False, en caso contrario
*/
function esVacio(str) {
    if (str == '' || str.replace(/ /g, '') == '') return true;
    return false;
}

/**
* Verifica la existencia de alg\xfan elemento HTML que tenga la propiedad value vac\xeda. 
* Los elementos verificados ser\xe1n aquellos cuyo id se encuentre en el rango <b>inicio-fin</b> inclusive. 
* Si el primer argumento es un array, entonces la verificaci\xf3n se har\xe1 entre los elementos
* cuyo id est\xe1 especificado en el array. En el caso de que el primer argumento sea un array, el segundo argumento ser\e1 omitido
* 
* @param {Integer, Array} inicio Id del primero elemento del rango a verificar. Si se provee un array,
* \xe9ste debe contener los Id's de los elementos a verificar.
* @param {Integer} fin Id del \xfaltimo elemento del rango a verificar.
* @returns {boolean} True, si alg\xfan elemento es vac\xedo; False, en caso contrario
*/
function hayVacio(inicio, fin) {
	if(arguments.length==1){
		arr = inicio;
		for(i in arr){
			if (esVacio(jQuery('#' + arr[i]).val())) return true;
		}
	}
	else{
		for (i = inicio; i <= fin; i++) {
			if (esVacio(jQuery('#' + i).val())) return true;
		}
	}
    return false;
}

/**
* Verifica la existencia de alg\xfan elemento HTML que tenga la propiedad value no vac\xeda. 
* Los elementos verificados ser\xe1n aquellos cuyo id se encuentre en el rango <b>inicio-fin</b> inclusive. 
* Si el primer argumento es un array, entonces la verificaci\xf3n se har\xe1 entre los elementos
* cuyo id est\xe1 especificado en el array. En el caso de que el primer argumento sea un array, el segundo argumento ser\e1 omitido
* 
* @param {Integer, Array} inicio Id del primero elemento del rango a verificar. Si se provee un array,
* \xe9ste debe contener los Id's de los elementos a verificar.
* @param {Integer} fin Id del \xfaltimo elemento del rango a verificar.
* @returns {boolean} True, si alg\xfan elemento es no vac\xedo; False, en caso contrario
*/
function hayNoVacio(inicio, fin) {
    for (i = inicio; i <= fin; i++) {
        if (!esVacio(jQuery('#' + i).val())) return true;
    }
    return false;
}

/**
* Quita los espacios en blanco del princiio y final de una cadena de texto
* 
* @param {String} str La cadena de texto que se quiere limpiar
* @returns {String} Cadena de texto sin espacios vac\xedos al principio ni al final
*/
function trim(str) {
    //Uso \xA0 porque IE no me reconoce \s
    if (str == null || typeof str === 'undefined') return '';
    return str.toString().replace(/^[\s\xA0]+/, '').replace(/[\s\xA0]+$/, '');
}

/**
* Coloca el foco en el objeto jQuery <b>objf</b> si el valor del objeto jQuery <b>obji/b<> cumple con las condiciones suministradas
* en el objeto <b>values</b>
* 
* @param {jQuery} obji Objeto del cual se verificara el valor para realizar el cambio de foco. Debe tener en cuenta que la verificaci\xf3n
* se realizar\xe1 sobre el evento jQuery keypress de <b>obji</b>.
* @param {jQuery} objf Objeto jQuery en el cual se colocar\xe1 el foco si se cumplen las condiciones.
* @param {object} values Objeto que provee las condiciones para realizar la validaci\xedn. Este objeto tiene la siguiente forma:
* {'<i>oper</i>':<i>datos</i>}, donde <i>oper</i> es el operador que se desea usa en la comparaci\xedn (actualemente son soportados:
* =,!=, >, <, >=, <=), y <i>datos</i> es un n\xfamero o un array conteniendo los valores a comparar con el operador. Ejemplos de este
* argumento son los siguientes: <br/>
* {'=':[1,9],'>':[12]} <br/>
* {'=':[1,9],'>=':12} <br/>
* {'=':[0,9]} <br/>
* {'!=':7} <br/>
* {'>='15} <br/>
* Si en <i>datos</i> se provee un array, la verificaci\xf3n se realiza con el operador l\xf3gico <b>OR</b> si <b>todosIguales</b>
* es falso y con el operador l\xf3gico <b>AND</b> en caso contrario.
* @param {boolean} cancelar Opcional. True por defecto. Esta bandera controla la cancelacion del evento. Para cancelar el evento se usa e.stopImmediatePropagation(),
* pero para IE se hace un retorno negativo (<code>return false</code>).
* @param {boolean} todosIguales Opcional. False por defecto. Esta bandera controla como se va a realizar la verificaci\xf3n de 
* los valores suministrados en <b>values</b>. Si True entonces la comparaci\xf3n se har\xe1 con <b>AND</b>, caso contario con <b>OR</b>
*/
function saltar(obji, objf, values, cancelar, todosIguales) {
    jQuery(obji).keypress(function(e) {
		/*
		 * {'=':[1,9],'>':[12]}
		 * {'=':[0,9]}
		 * {'!=':7}
		 * {'>='15}
		*/
		cancelar = typeof cancelar === 'undefined'? true:cancelar;
		todosIguales = typeof todosIguales === 'undefined'? false:todosIguales;
        if (e.keyCode != 13) return;
		var _cumple=false;
		jQuery.each(values,function(key, val){
			if(cumpleAlguno(jQuery(obji).val(), val, key, todosIguales)){
				_cumple = true;
				jQuery(objf).focus();
				if(cancelar===true){
					e.stopImmediatePropagation();
				}
			}
		});
		if(_cumple==true){
			return false	//para IE
		}
    });
}

/**
* 
*/
function cumpleAlguno(val1, val2, oper, todos){
	var continuar;
	if(jQuery.isArray(val2)){
		
		if(val2.length==0) return false;
		
		if(todos===true){
			continuar = true;
			for(i=0; i<val2.length; i++){
				continuar = continuar && comparar(val1, val2[i], oper, typeof val2[i]);
			}
			return continuar;
		}
		else{
			for(i=0; i<val2.length; i++){
				if(comparar(val1, val2[i], oper, typeof val2[i])) return true;
			}
			return false;
		}
	}
	else return comparar(val1, val2, oper, typeof val2);
}

function comparar(val1, val2, oper, type){
	if(type === 'string'){
		if(oper == '='){
			return val1.toString() === val2.toString();
		}
		else if(oper == '!='){
			return val1.toString() !== val2.toString();
		}
		return false;
	}
	else if(type === 'number'){
		//si  val1 no es un numero no hace falta ninguna comparacion, de cualquier forma no
		//cumplira ninguna de las condiciones
		if(isNaN(parseFloat(val1))) return false;
		
		if(oper == '='){
			return parseFloat(val1) === parseFloat(val2);
		}
		else if(oper == '!='){
			return parseFloat(val1) !== parseFloat(val2);
		}
		else if(oper == '>'){
			return parseFloat(val1) > parseFloat(val2);
		}
		else if(oper == '<'){
			return parseFloat(val1) < parseFloat(val2);
		}
		else if(oper == '>='){
			return parseFloat(val1) >= parseFloat(val2);
		}
		else if(oper == '<='){
			return parseFloat(val1) <= parseFloat(val2);
		}
		return false;
	}
}

function idVacio(inicio, fin) {
	if(arguments.length == 1){
		arr = inicio;
		for(i in arr){
			if ( esVacio(jQuery('#' + arr[i]).val()) ) return arr[i];
		}
	}
	else{
		for (i = inicio; i <= fin; i++) {
			if (esVacio(jQuery('#' + i).val())) return i;
		}
	}
    return -1;
}

function idNoVacio(inicio, fin) {
	if(arguments.length == 1){
		arr = inicio;
		for(i in arr){
			if ( !esVacio(jQuery('#' + arr[i]).val()) ) return arr[i];
		}
	}
	else{
		for (i = inicio; i <= fin; i++) {
			if (!esVacio(jQuery('#' + i).val())) return i;
		}
	}
    return -1;
}

function hayRepetidos(str){
	if (typeof str === 'undefined') return false;
	str = typeof str !== 'string' ? str.toString():str;
	if (esVacio(str)) return false;
	
	var len1 = str.split('').length;
	var len2 = jQuery.unique(str.split('')).length;
	
	return len1 != len2;
}


(function(jQuery, undefined){
	  jQuery.fn.rango = function(minimo, maximo, omision, otros){
		minimo = typeof minimo === 'number' ? parseFloat(minimo): '#';
		maximo = typeof maximo === 'number' ? parseFloat(maximo): '#';
		omision = typeof omision === 'undefined' ? false : omision;
		otros = typeof otros === 'undefined' ? [] : otros;
		if(minimo === '#' || maximo === '#') return;
		
		jQuery(this).blur(function(e) {
			var val = parseFloat(jQuery(this).val());
			if( (val<minimo || val>maximo || cumpleAlguno(val, otros, '=', false) ) && val.toString() !== omision.toString()) {
				if(omision === false){
					alert('El valor ingresado esta fuera del rango. Los valores permitidos van desde "' + minimo + '" hasta "' + maximo + '" y no existe valor por omisi\xf3n"');
				}
				else{	
					alert('El valor ingresado esta fuera del rango. Los valores permitidos van desde "' + minimo + '" hasta "' + maximo + '" y el valor por omisi\xf3n es "' + omision + '"');
				}
				var _el = this;
				window.setTimeout(function(){jQuery(_el).focus();},0);
			}
        });
	}
})(jQuery);

function getSelection(el) {
    var start = 0, end = 0, normalizedValue, range,
        textInputRange, len, endRange, el=jQuery(el)[0];

    if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
        start = el.selectionStart;
        end = el.selectionEnd;
    } else {
        range = document.selection.createRange();

        if (range && range.parentElement() == el) {
            len = el.value.length;
            //normalizedValue = el.value.replace(/\r\n/g, "\n");
			normalizedValue = el.value.replace(/\r\n/g, "");

            // Create a working TextRange that lives only in the input
            textInputRange = el.createTextRange();
            textInputRange.moveToBookmark(range.getBookmark());

            // Check if the start and end of the selection are at the very end
            // of the input, since moveStart/moveEnd doesn't return what we want
            // in those cases
            endRange = el.createTextRange();
            endRange.collapse(false);

            if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
                start = end = len;
            } else {
                start = -textInputRange.moveStart("character", -len);
                start += normalizedValue.slice(0, start).split("\n").length - 1;

                if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
                    end = len;
                } else {
                    end = -textInputRange.moveEnd("character", -len);
                    end += normalizedValue.slice(0, end).split("\n").length - 1;
                }
            }
        }
    }

    return {
        begin: start,
        end: end
    };
}

String.prototype.endWith = function(suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
}

String.prototype.startWith = function(prefix) {
    return this.indexOf(prefix) === 0;
}

/**
* Indica el numero de veces que aparece un caracter en la cadena de texto
*/
String.prototype.contar = function(car){
	var cant = 0;
	var lastPos = -1;
	while( (lastPos = this.indexOf(car,lastPos+1)) != -1 ){
		cant++;
	}
	return cant
}